在 day4、day5 用到的 require
、import
等語法,其實就是 JavaScript 內建的模組化寫法。但其實 JavaScript 被創始之初,是沒有模組化方案的。
因此,早期的 JavaScript 開發者為了讓網頁開發更有條理,就在規範還不支援的情況下,土砲了許多模組化方案。直至今日,雖然 ECMAScript 已經有了內建的模組系統,但在瀏覽器端與 Node.js 端上仍然不完備。以下是簡單的 JavaScript 模組規範歷史整理:
瀏覽器端 | 伺服器端 | |
---|---|---|
globals。透過立即函式、物件實現命名空間。 | - ( - 表伺服器端用法相似) | |
2009 | CommonJS 規範。Node.js 初期有遵守此規範。若想在瀏覽器上用 CommonJS 的模組規範,可透過 Browerify、webpack 等 module bundler 來轉成瀏覽器看得懂的模組規範(如 AMD 規範)。 | |
2011 | AMD, CMD 規範。實現了 AMD 規範的 module loader 有 require.js,而實現了 CMD 規範的則有 sea.js。 | |
2011 | UMD 規範。兼容 AMD、CommonJS規範寫法 | - |
2013 | SystemJS,一種 module loader,可導入 CommonJS、UMD、AMD、ES6 的模組。 | - |
2015 | ES6 Modules。ECMAScript 的官方內建模組規範。在瀏覽器端用 script 引入要添加 type=module。在伺服器端使用須將 .js 後綴名改成 .jsm。雖然規範已定,但如何實現還沒塵埃落定,所以使用細節可能會再有變動。 | - |
在這次系列文中,會用到的只有 CommonJS、ES6 Modules 這兩組模組規範,因此將重點介紹這兩種。
CommonJS 模組規範,是 Mozilla 工程師 Kevin Dangoor 在 2009 年 1 月提出,最初名為ServerJS,而後在同年 8 月改名 CommonJS。目前主要有使用 CommonJS 規範的項目有 Node.js。因此,如果要在後端用 JavaScript 的模組系統的話,在早期都是用 CommonJS 的語法形式。
在 Day5 的時候,有寫到 gulp 的引入、導出模組時的 CommonJS 寫法。主要用法是,要導入模組時,就用 require('模組名稱')
,在範例中這樣寫 const gulp = require('gulp')
。要導出模組時,就用 exports.想被使用的名字 = 想導出的函式或變數
,在範例中是這樣寫 exports.hello4CommonJS = hello4CommonJS
。
// gulpfile.js
// 在 CLI 輸入 gulp hello4CommonJS,會印出 hello gulp , CommonJS format
const gulp = require('gulp')
function hello4CommonJS(cb) {
console.log('hello gulp 4.0, CommonJS format' )
cb();
}
exports.hello4CommonJS = hello4CommonJS
ES6 Modules,簡稱 ESM,是 ECMA TC39 組織在 2015 推出的 JavaScript 內建模組功能,親兒子來著。
在 Day5 的時候,有寫到 gulp 的引入、導出模組時的 CommonJS 寫法。主要用法是,要導入模組時,就用 import 想被使用的名字 from '模組名字'
,在範例中這樣寫 import gulp from 'gulp'
。要導出模組時,就用 exports 想導出的函式或變數
,在範例中是這樣寫 export function hello4ES6(){}
。
// gulpfile.babel.js
// 在 CLI 輸入 gulp hello4ES6,會印出 hello gulp 4.0, ES6 format
import gulp from 'gulp'
export function hello4ES6(cb) {
console.log('hello gulp 4.0, ES6 format')
cb()
}
在 ESM 方案出來前,在 Node.js 上都是用 CommonJS 規範的 require
、exports
語法來操作模組。但有了 babel、webpack 等工具出來後,就算 ESM 的實現還不成熟,但已經有著正式使用的品質了。在接下來的數日,會主要使用 ESM 的語法來操作模組。
在 hello gulp 篇,整理了 glup 3.9.1 與 gulp 4 的寫法差異,以及 CommonJS 與 ESM 規範的寫法差異。明天就來個稍微實用一點的 task:複製檔案吧。
JS module 比較
CommonJS
AMD
CMD
UMD
system.js
ES6 module
瀏覽器端 HTML 的 script[type=module]